module Digit2word
  class Convert
    attr_reader :argv
    def initialize(argv = ARGV)
      @argv = argv
      @paths = @argv.map {|path| Digit2word.root.join(path).to_s}
    end

    def run!
      @paths.each{|path| convert_file(path)}
    end

    private
    def digit_character_map
      @digit_character_map ||= File.open(APP_CONFIG) { |file| YAML.load(file) }[:digit_character_map]
    end

    def convert_file(file_path)
      if File.exist?(file_path)
        puts "Operating: #{file_path}"
        File.new(file_path).each do |line|
          matched_words = convert_number_with_pattern(line, Digit2word::Dict.word_pattern)
          if !matched_words.empty?
            puts "Matched words for: #{line.strip}"
            puts matched_words
            puts ''
          end
        end
        puts ''
      else
        puts "File Not Found: #{file_path}"
      end
    end

    def convert_number_with_pattern(number, pattern)
      number.strip!
      matched_words = []
      character_seed = number.split('').map{|x| digit_character_map[x.to_i] || [x]}
      character_seed.first.product(*character_seed[1..-1]).each do |word_arr|
        if !(matched_arr = word_arr.join('').scan(pattern)).empty?
          matched_hash = matched_arr.inject({}){|hash, x| hash[character_to_number(x)] = x; hash}
          blank_word = number.gsub(Regexp.new(matched_hash.keys.join('|'), true), matched_hash)
          matched_words << clean_up_word(blank_word)
        end
      end
      matched_words.uniq!
    end

    def character_to_number(character)
      numbers = []
      character.each_char do |char|
        numbers << (digit_character_map.find{|k, v| v.include?(char.upcase)}.first || char)
      end
      numbers.join('')
    end

    def clean_up_word(word)
      word.gsub(/[^\w]/, '-')
    end
  end
end
